﻿using System;

class SpiralMatrix
{
	static void Main(string[] args)
	{
		byte matrixSize;//matrixsize 4x4 or 5x5...
		bool isDataValid;
		int stepForPrinting; //needed to space out for 1, 2 or 3 digits
		do
		{
			Console.WriteLine("Enter a positive integer number in the range [1,20]:");
			isDataValid = Byte.TryParse(Console.ReadLine(), out matrixSize);
			if ((matrixSize == 0) || (matrixSize > 20) || (!isDataValid))
			{
				Console.WriteLine("You must enter an integer number in the range [1,20]!\n");
				isDataValid = false;
			}
		} while (!isDataValid);
		if (matrixSize <= 3)
		{
			stepForPrinting = 2; //kolko intervala za matrixa 3x3 = 9 maxnumber edin interval i chislo
		}
		else if (matrixSize <= 9)
		{
			stepForPrinting = 3;
		}
		else
		{
			stepForPrinting = 4;
		}
		int maxNumber = matrixSize * matrixSize;
		byte whereToStart = 0;
		byte currentRowOrColumn = 0;
		int currentPosition;
		int temporaryMatrixSize = matrixSize * stepForPrinting; //za puyrvite 9 simvola
		const byte right = 1;
		const byte down = 2;
		const byte left = 3;
		const byte top = 4;
		byte direction = right;
		Console.Clear();
		for (int currentNumber = 1; currentNumber <= maxNumber; )
		{
			switch (direction)
			{
				case right:
					for (currentPosition = whereToStart; currentPosition < temporaryMatrixSize - whereToStart; //currentpositiuon<6
						currentPosition += stepForPrinting, currentNumber++)
					{
						Console.SetCursorPosition(currentPosition, currentRowOrColumn); //0,0 2,0 4,0
						Console.Write(currentNumber); // 0 1 2 
						
					}
					direction = down;
					whereToStart = currentRowOrColumn;
					currentRowOrColumn = (byte)(currentPosition - stepForPrinting);
					break;
				case down:
					for (currentPosition = whereToStart + 1; currentPosition < matrixSize - whereToStart;
						currentPosition++, currentNumber++)
					{
						Console.SetCursorPosition(currentRowOrColumn, currentPosition);
						Console.Write(currentNumber);
					}
					direction = left;
					whereToStart = currentRowOrColumn;
					currentRowOrColumn = (byte)(currentPosition - 1);
					break;
				case left:
					for (currentPosition = whereToStart - stepForPrinting; currentPosition >= temporaryMatrixSize - stepForPrinting * (1 + currentRowOrColumn);
						currentPosition -= stepForPrinting, currentNumber++)
					{
						Console.SetCursorPosition(currentPosition, currentRowOrColumn);
						Console.Write(currentNumber);
					}
					currentPosition += stepForPrinting;
					direction = top;
					whereToStart = (byte)(currentRowOrColumn - 1);
					currentRowOrColumn = (byte)currentPosition;
					break;
				case top:
					for (currentPosition = whereToStart; currentPosition >= matrixSize - whereToStart - 1;
						currentPosition -= 1, currentNumber++)
					{
						Console.SetCursorPosition(currentRowOrColumn, currentPosition);
						Console.Write(currentNumber);
					}
					direction = right;
					whereToStart = (byte)(currentRowOrColumn + stepForPrinting);
					currentRowOrColumn = (byte)(currentPosition + 1);

					break;
				default:
					break;
			}
		}
		Console.ReadKey();
	}
}